.ci/deploy-docs.sh | 25 + .travis.yml | 3 docs/HarfBuzz.png |binary docs/Makefile.am | 16 - docs/harfbuzz-docs.xml | 54 +++- docs/usermanual-buffers-language-script-and-direction.xml | 77 +++++ docs/usermanual-ch01.xml | 115 -------- docs/usermanual-ch02.xml | 183 -------------- docs/usermanual-ch03.xml | 77 ----- docs/usermanual-ch04.xml | 18 - docs/usermanual-ch05.xml | 13 docs/usermanual-ch06.xml | 8 docs/usermanual-fonts-and-faces.xml | 18 + docs/usermanual-glyph-information.xml | 8 docs/usermanual-hello-harfbuzz.xml | 183 ++++++++++++++ docs/usermanual-install-harfbuzz.xml | 70 +++++ docs/usermanual-opentype-features.xml | 13 docs/usermanual-what-is-harfbuzz.xml | 115 ++++++++ 18 files changed, 564 insertions(+), 432 deletions(-)
New commits: commit e5b90c08a4c1f475560209a5e47628f695606d89 Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 25 18:41:41 2015 +0100 [travis] Remove secure var I've set up a secure var for behdad/harfbuzz through Travis web interface, no need to set the var here. diff --git a/.ci/deploy-docs.sh b/.ci/deploy-docs.sh index 8c60a22..bbd64df 100755 --- a/.ci/deploy-docs.sh +++ b/.ci/deploy-docs.sh @@ -1,6 +1,6 @@ set -o errexit -o nounset -if [ "$TRAVIS_OS_NAME" == "linux" -a "$CC" == "gcc" -a "$TRAVIS_PULL_REQUEST" == "false" -a "$TRAVIS_BRANCH" == "master" ] +if [ "$TRAVIS_OS_NAME" == "linux" -a "$CC" == "gcc" -a "$TRAVIS_SECURE_ENV_VARS" == "true" -a "$TRAVIS_PULL_REQUEST" == "false" -a "$TRAVIS_BRANCH" == "master" ] then DOCSDIR=build-docs REVISION=$(git rev-parse --short HEAD) diff --git a/.travis.yml b/.travis.yml index 798f5ee..89f4012 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,6 @@ env: - CFLAGS="-Werror --coverage" - CXXFLAGS="-Werror --coverage" - LDFLAGS="--coverage" - - secure: "EysLG1MB6WCvDVpls5jsJAYsXcbHTmSFYl11UlAQCNfU+MBv7qiuOR6im3tM4ISzt4TY+OQXxEktMFRT+8govLR4UWo8dwmZ4P/2GqMbsZNPVSLkbDEy6hVv7xe5X4mp+npHthY1Z1YOLKGAh/u1PymySZz6qAzsCZ6Fq/H5Ri8=" install: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then pip install --user nose; fi - if [ "$TRAVIS_OS_NAME" == "linux" ]; then pip install --user cpp-coveralls; fi # for coveralls.io code coverage tracking commit e75c1ffdf548185ce1f1df7937f0d028e5e40efe Merge: 6173c2a d25317f Author: Behdad Esfahbod <beh...@behdad.org> Date: Fri Dec 25 18:21:08 2015 +0100 Merge pull request #199 from behdad/travis-docs Deploy docs to gh-pages branch from Travis builds commit d25317f67f3c5c77f9059961935b0f35cbaa9ac4 Author: Khaled Hosny <khaledho...@eglug.org> Date: Wed Dec 23 01:29:48 2015 +0400 Move more docs from FreeDesktop page diff --git a/docs/Makefile.am b/docs/Makefile.am index 05a27db..5e6fd2b 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -75,6 +75,7 @@ content_files= \ usermanual-fonts-and-faces.xml \ usermanual-glyph-information.xml \ usermanual-hello-harfbuzz.xml \ + usermanual-install-harfbuzz.xml \ usermanual-opentype-features.xml \ usermanual-what-is-harfbuzz.xml \ version.xml diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 49252f7..7d2232f 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -7,11 +7,6 @@ <book id="index"> <bookinfo> <title>HarfBuzz Manual</title> - <releaseinfo> - This document is for HarfBuzz &version;. - <!--The latest version of this documentation can be found on-line at - <ulink role="online-location" url="http://[SERVER]/libharfbuzz/index.html">http://[SERVER]/libharfbuzz/</ulink>.--> - </releaseinfo> <abstract> <title>HarfBuzz</title> <graphic fileref="HarfBuzz.png" format="PNG" align="center"/> @@ -28,7 +23,7 @@ <ulink url="http://cgit.freedesktop.org/harfbuzz/">here</ulink>. Also available on <ulink url="https://github.com/behdad/harfbuzz">github</ulink>. - See below for release tarballs. + See <xref linkend="download" endterm="download.title"/> for release tarballs. </para> <para> The old HarfBuzz codebase, these days known as harfbuzz-old, was @@ -46,6 +41,7 @@ <part> <title>User's manual</title> <xi:include href="usermanual-what-is-harfbuzz.xml"/> + <xi:include href="usermanual-install-harfbuzz.xml"/> <xi:include href="usermanual-hello-harfbuzz.xml"/> <xi:include href="usermanual-buffers-language-script-and-direction.xml"/> <xi:include href="usermanual-fonts-and-faces.xml"/> @@ -54,6 +50,13 @@ </part> <part> + <partinfo> + <releaseinfo> + This document is for HarfBuzz &version;. + <!--The latest version of this documentation can be found on-line at + <ulink role="online-location" url="http://[SERVER]/libharfbuzz/index.html">http://[SERVER]/libharfbuzz/</ulink>.--> + </releaseinfo> + </partinfo> <title>Reference manual</title> <chapter> <title>Harfbuzz API</title> diff --git a/docs/usermanual-install-harfbuzz.xml b/docs/usermanual-install-harfbuzz.xml new file mode 100644 index 0000000..be8ac8d --- /dev/null +++ b/docs/usermanual-install-harfbuzz.xml @@ -0,0 +1,70 @@ +<chapter id="install-harfbuzz"> + <title>Install Harfbuzz</title> + <section id="download"> + <title id="download.title">Download</title> + <para> + For tarball releases of HarfBuzz, look + <ulink url="http://www.freedesktop.org/software/harfbuzz/release/">here</ulink>. + At the same place you will + also find Win32 binary bundles that include libharfbuzz DLL, hb-view.exe, + hb-shape.exe, and all dependencies. + </para> + <para> + The canonical source tree is available + <ulink url="http://cgit.freedesktop.org/harfbuzz/">here</ulink>. + Also available on <ulink url="https://github.com/behdad/harfbuzz">github</ulink>. + </para> + <para> + The API that comes with <filename class='headerfile'>hb.h</filename> will + not change incompatibly. Other, peripheral, headers are more likely to go + through minor modifications, but again, will do our best to never change + API in an incompatible way. We will never break the ABI. + </para> + <para> + If you are not sure whether Pango or HarfBuzz is right for you, read + <ulink url="http://mces.blogspot.in/2009/11/pango-vs-harfbuzz.html">this</ulink>. + </para> + </section> + <section id="building"> + <title>Building</title> + <para> + On Linux, install the development packages for FreeType, Cairo, and GLib. + For example, on Ubuntu / Debian, you would do: + <programlisting> +<command>sudo apt-get install</command> <package>gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev</package> + </programlisting> + whereas on Fedora, RHEL, CentOS, and other Red Hat based systems you would do: + <programlisting> +<command>sudo yum install</command> <package>gcc gcc-c++ freetype-devel glib2-devel cairo-devel</package> + </programlisting> + or using MacPorts: + <programlisting> +<command>sudo port install</command> <package>freetype glib2 cairo</package> + </programlisting> + </para> + <para> + If you are using a tarball, you can now proceed to running + <command>configure</command> and <command>make</command> as with any + other standard package. That should leave you with a shared library in + <filename>src/</filename>, and a few utility programs including hb-view + and hb-shape under <filename>util/</filename>. + </para> + <para> + If you are bootstraping from git, you need a few more tools before you + can run <filename>autogen.sh</filename> for the first time. Namely, + pkg-config and <ulink url="http://www.complang.org/ragel/">ragel</ulink>. + Again, on Ubuntu / Debian: + <programlisting> +<command>sudo apt-get install</command> <package>autoconf automake libtool pkg-config ragel gtk-doc-tools</package> + </programlisting> + and on Fedora, RHEL, CentOS: + <programlisting> +<command>sudo yum install</command> <package>autoconf automake libtool pkgconfig ragel gtk-doc</package> + </programlisting> + or using MacPorts: + <programlisting> +<command>sudo port install</command> <package>autoconf automake libtool pkgconfig ragel gtk-doc</package> + </programlisting> + </para> + </section> +</chapter> commit 493a92220844c8996be67c8a7a2c5447942fe2c1 Author: Khaled Hosny <khaledho...@eglug.org> Date: Wed Dec 23 00:33:41 2015 +0400 Rename user manual files Use chapter ids instead of numbers, so that we can reorder them, introduce new ones etc. without the numbers becoming out of date. diff --git a/docs/Makefile.am b/docs/Makefile.am index 64344b8..05a27db 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -71,12 +71,12 @@ HTML_IMAGES= \ # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml content_files= \ - usermanual-ch01.xml \ - usermanual-ch02.xml \ - usermanual-ch03.xml \ - usermanual-ch04.xml \ - usermanual-ch05.xml \ - usermanual-ch06.xml \ + usermanual-buffers-language-script-and-direction.xml \ + usermanual-fonts-and-faces.xml \ + usermanual-glyph-information.xml \ + usermanual-hello-harfbuzz.xml \ + usermanual-opentype-features.xml \ + usermanual-what-is-harfbuzz.xml \ version.xml # SGML files where gtk-doc abbrevations (#GtkWidget) are expanded diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index a7efbf8..49252f7 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -45,12 +45,12 @@ <part> <title>User's manual</title> - <xi:include href="usermanual-ch01.xml"/> - <xi:include href="usermanual-ch02.xml"/> - <xi:include href="usermanual-ch03.xml"/> - <xi:include href="usermanual-ch04.xml"/> - <xi:include href="usermanual-ch05.xml"/> - <xi:include href="usermanual-ch06.xml"/> + <xi:include href="usermanual-what-is-harfbuzz.xml"/> + <xi:include href="usermanual-hello-harfbuzz.xml"/> + <xi:include href="usermanual-buffers-language-script-and-direction.xml"/> + <xi:include href="usermanual-fonts-and-faces.xml"/> + <xi:include href="usermanual-opentype-features.xml"/> + <xi:include href="usermanual-glyph-information.xml"/> </part> <part> diff --git a/docs/usermanual-buffers-language-script-and-direction.xml b/docs/usermanual-buffers-language-script-and-direction.xml new file mode 100644 index 0000000..3a26c55 --- /dev/null +++ b/docs/usermanual-buffers-language-script-and-direction.xml @@ -0,0 +1,77 @@ +<chapter id="buffers-language-script-and-direction"> + <title>Buffers, language, script and direction</title> + <para> + The input to Harfbuzz is a series of Unicode characters, stored in a + buffer. In this chapter, we'll look at how to set up a buffer with + the text that we want and then customize the properties of the + buffer. + </para> + <section id="creating-and-destroying-buffers"> + <title>Creating and destroying buffers</title> + <para> + As we saw in our initial example, a buffer is created and + initialized with <literal>hb_buffer_create()</literal>. This + produces a new, empty buffer object, instantiated with some + default values and ready to accept your Unicode strings. + </para> + <para> + Harfbuzz manages the memory of objects that it creates (such as + buffers), so you don't have to. When you have finished working on + a buffer, you can call <literal>hb_buffer_destroy()</literal>: + </para> + <programlisting language="C"> + hb_buffer_t *buffer = hb_buffer_create(); + ... + hb_buffer_destroy(buffer); +</programlisting> + <para> + This will destroy the object and free its associated memory - + unless some other part of the program holds a reference to this + buffer. If you acquire a Harfbuzz buffer from another subsystem + and want to ensure that it is not garbage collected by someone + else destroying it, you should increase its reference count: + </para> + <programlisting language="C"> +void somefunc(hb_buffer_t *buffer) { + buffer = hb_buffer_reference(buffer); + ... +</programlisting> + <para> + And then decrease it once you're done with it: + </para> + <programlisting language="C"> + hb_buffer_destroy(buffer); +} +</programlisting> + <para> + To throw away all the data in your buffer and start from scratch, + call <literal>hb_buffer_reset(buffer)</literal>. If you want to + throw away the string in the buffer but keep the options, you can + instead call <literal>hb_buffer_clear_contents(buffer)</literal>. + </para> + </section> + <section id="adding-text-to-the-buffer"> + <title>Adding text to the buffer</title> + <para> + Now we have a brand new Harfbuzz buffer. Let's start filling it + with text! From Harfbuzz's perspective, a buffer is just a stream + of Unicode codepoints, but your input string is probably in one of + the standard Unicode character encodings (UTF-8, UTF-16, UTF-32) + </para> + </section> + <section id="setting-buffer-properties"> + <title>Setting buffer properties</title> + <para> + </para> + </section> + <section id="what-about-the-other-scripts"> + <title>What about the other scripts?</title> + <para> + </para> + </section> + <section id="customizing-unicode-functions"> + <title>Customizing Unicode functions</title> + <para> + </para> + </section> +</chapter> \ No newline at end of file diff --git a/docs/usermanual-ch01.xml b/docs/usermanual-ch01.xml deleted file mode 100644 index 3574d75..0000000 --- a/docs/usermanual-ch01.xml +++ /dev/null @@ -1,115 +0,0 @@ -<chapter id="what-is-harfbuzz"> - <title>What is Harfbuzz?</title> - <para> - Harfbuzz is a <emphasis>text shaping engine</emphasis>. It solves - the problem of selecting and positioning glyphs from a font given a - Unicode string. - </para> - <section id="why-do-i-need-it"> - <title>Why do I need it?</title> - <para> - Text shaping is an integral part of preparing text for display. It - is a fairly low level operation; Harfbuzz is used directly by - graphic rendering libraries such as Pango, and the layout engines - in Firefox, LibreOffice and Chromium. Unless you are - <emphasis>writing</emphasis> one of these layout engines yourself, - you will probably not need to use Harfbuzz - normally higher level - libraries will turn text into glyphs for you. - </para> - <para> - However, if you <emphasis>are</emphasis> writing a layout engine - or graphics library yourself, you will need to perform text - shaping, and this is where Harfbuzz can help you. Here are some - reasons why you need it: - </para> - <itemizedlist> - <listitem> - <para> - OpenType fonts contain a set of glyphs, indexed by glyph ID. - The glyph ID within the font does not necessarily relate to a - Unicode codepoint. For instance, some fonts have the letter - "a" as glyph ID 1. To pull the right glyph out of - the font in order to display it, you need to consult a table - within the font (the "cmap" table) which maps - Unicode codepoints to glyph IDs. Text shaping turns codepoints - into glyph IDs. - </para> - </listitem> - <listitem> - <para> - Many OpenType fonts contain ligatures: combinations of - characters which are rendered together. For instance, it's - common for the <literal>fi</literal> combination to appear in - print as the single ligature "ï¬". Whether you should - render text as <literal>fi</literal> or "ï¬" does not - depend on the input text, but on the capabilities of the font - and the level of ligature application you wish to perform. - Text shaping involves querying the font's ligature tables and - determining what substitutions should be made. - </para> - </listitem> - <listitem> - <para> - While ligatures like "ï¬" are typographic - refinements, some languages <emphasis>require</emphasis> such - substitutions to be made in order to display text correctly. - In Tamil, when the letter "TTA" (à®) letter is - followed by "U" (à®), the combination should appear - as the single glyph "à®à¯". The sequence of Unicode - characters "à®à®" needs to be rendered as a single - glyph from the font - text shaping chooses the correct glyph - from the sequence of characters provided. - </para> - </listitem> - <listitem> - <para> - Similarly, each Arabic character has four different variants: - within a font, there will be glyphs for the initial, medial, - final, and isolated forms of each letter. Unicode only encodes - one codepoint per character, and so a Unicode string will not - tell you which glyph to use. Text shaping chooses the correct - form of the letter and returns the correct glyph from the font - that you need to render. - </para> - </listitem> - <listitem> - <para> - Other languages have marks and accents which need to be - rendered in certain positions around a base character. For - instance, the Moldovan language has the Cyrillic letter - "zhe" (ж) with a breve accent, like so: Ó. Some - fonts will contain this character as an individual glyph, - whereas other fonts will not contain a zhe-with-breve glyph - but expect the rendering engine to form the character by - overlaying the two glyphs ж and Ë. Where you should draw the - combining breve depends on the height of the preceding glyph. - Again, for Arabic, the correct positioning of vowel marks - depends on the height of the character on which you are - placing the mark. Text shaping tells you whether you have a - precomposed glyph within your font or if you need to compose a - glyph yourself out of combining marks, and if so, where to - position those marks. - </para> - </listitem> - </itemizedlist> - <para> - If this is something that you need to do, then you need a text - shaping engine: you could use Uniscribe if you are using Windows; - you could use CoreText on OS X; or you could use Harfbuzz. In the - rest of this manual, we are going to assume that you are the - implementor of a text layout engine. - </para> - </section> - <section id="why-is-it-called-harfbuzz"> - <title>Why is it called Harfbuzz?</title> - <para> - Harfbuzz began its life as text shaping code within the FreeType - project, (and you will see references to the FreeType authors - within the source code copyright declarations) but was then - abstracted out to its own project. This project is maintained by - Behdad Esfahbod, and named Harfbuzz. Originally, it was a shaping - engine for OpenType fonts - "Harfbuzz" is the Persian - for "open type". - </para> - </section> -</chapter> \ No newline at end of file diff --git a/docs/usermanual-ch02.xml b/docs/usermanual-ch02.xml deleted file mode 100644 index 34db017..0000000 --- a/docs/usermanual-ch02.xml +++ /dev/null @@ -1,183 +0,0 @@ -<chapter id="hello-harfbuzz"> - <title>Hello, Harfbuzz</title> - <para> - Here's the simplest Harfbuzz that can possibly work. We will improve - it later. - </para> - <orderedlist numeration="arabic"> - <listitem> - <para> - Create a buffer and put your text in it. - </para> - </listitem> - </orderedlist> - <programlisting language="C"> - #include <hb.h> - hb_buffer_t *buf; - buf = hb_buffer_create(); - hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); -</programlisting> - <orderedlist numeration="arabic"> - <listitem override="2"> - <para> - Guess the script, language and direction of the buffer. - </para> - </listitem> - </orderedlist> - <programlisting language="C"> - hb_buffer_guess_segment_properties(buf); -</programlisting> - <orderedlist numeration="arabic"> - <listitem override="3"> - <para> - Create a face and a font, using FreeType for now. - </para> - </listitem> - </orderedlist> - <programlisting language="C"> - #include <hb-ft.h> - FT_New_Face(ft_library, font_path, index, &face) - hb_font_t *font = hb_ft_font_create(face); -</programlisting> - <orderedlist numeration="arabic"> - <listitem override="4"> - <para> - Shape! - </para> - </listitem> - </orderedlist> - <programlisting> - hb_shape(font, buf, NULL, 0); -</programlisting> - <orderedlist numeration="arabic"> - <listitem override="5"> - <para> - Get the glyph and position information. - </para> - </listitem> - </orderedlist> - <programlisting language="C"> - hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count); - hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count); -</programlisting> - <orderedlist numeration="arabic"> - <listitem override="6"> - <para> - Iterate over each glyph. - </para> - </listitem> - </orderedlist> - <programlisting language="C"> - for (i = 0; i < glyph_count; ++i) { - glyphid = glyph_info[i].codepoint; - x_offset = glyph_pos[i].x_offset / 64.0; - y_offset = glyph_pos[i].y_offset / 64.0; - x_advance = glyph_pos[i].x_advance / 64.0; - y_advance = glyph_pos[i].y_advance / 64.0; - draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); - cursor_x += x_advance; - cursor_y += y_advance; - } -</programlisting> - <orderedlist numeration="arabic"> - <listitem override="7"> - <para> - Tidy up. - </para> - </listitem> - </orderedlist> - <programlisting language="C"> - hb_buffer_destroy(buf); - hb_font_destroy(hb_ft_font); -</programlisting> - <section id="what-harfbuzz-doesnt-do"> - <title>What Harfbuzz doesn't do</title> - <para> - The code above will take a UTF8 string, shape it, and give you the - information required to lay it out correctly on a single - horizontal (or vertical) line using the font provided. That is the - extent of Harfbuzz's responsibility. - </para> - <para> - If you are implementing a text layout engine you may have other - responsibilities, that Harfbuzz will not help you with: - </para> - <itemizedlist> - <listitem> - <para> - Harfbuzz won't help you with bidirectionality. If you want to - lay out text with mixed Hebrew and English, you will need to - ensure that the buffer provided to Harfbuzz has those - characters in the correct layout order. This will be different - from the logical order in which the Unicode text is stored. In - other words, the user will hit the keys in the following - sequence: - </para> - <programlisting> -A B C [space] × × × [space] D E F - </programlisting> - <para> - but will expect to see in the output: - </para> - <programlisting> -ABC ××× DEF - </programlisting> - <para> - This reordering is called <emphasis>bidi processing</emphasis> - ("bidi" is short for bidirectional), and there's an - algorithm as an annex to the Unicode Standard which tells you how - to reorder a string from logical order into presentation order. - Before sending your string to Harfbuzz, you may need to apply the - bidi algorithm to it. Libraries such as ICU and fribidi can do - this for you. - </para> - </listitem> - <listitem> - <para> - Harfbuzz won't help you with text that contains different font - properties. For instance, if you have the string "a - <emphasis>huge</emphasis> breakfast", and you expect - "huge" to be italic, you will need to send three - strings to Harfbuzz: <literal>a</literal>, in your Roman font; - <literal>huge</literal> using your italic font; and - <literal>breakfast</literal> using your Roman font again. - Similarly if you change font, font size, script, language or - direction within your string, you will need to shape each run - independently and then output them independently. Harfbuzz - expects to shape a run of characters sharing the same - properties. - </para> - </listitem> - <listitem> - <para> - Harfbuzz won't help you with line breaking, hyphenation or - justification. As mentioned above, it lays out the string - along a <emphasis>single line</emphasis> of, notionally, - infinite length. If you want to find out where the potential - word, sentence and line break points are in your text, you - could use the ICU library's break iterator functions. - </para> - <para> - Harfbuzz can tell you how wide a shaped piece of text is, which is - useful input to a justification algorithm, but it knows nothing - about paragraphs, lines or line lengths. Nor will it adjust the - space between words to fit them proportionally into a line. If you - want to layout text in paragraphs, you will probably want to send - each word of your text to Harfbuzz to determine its shaped width - after glyph substitutions, then work out how many words will fit - on a line, and then finally output each word of the line separated - by a space of the correct size to fully justify the paragraph. - </para> - </listitem> - </itemizedlist> - <para> - As a layout engine implementor, Harfbuzz will help you with the - interface between your text and your font, and that's something - that you'll need - what you then do with the glyphs that your font - returns is up to you. The example we saw above enough to get us - started using Harfbuzz. Now we are going to use the remainder of - Harfbuzz's API to refine that example and improve our text shaping - capabilities. - </para> - </section> -</chapter> \ No newline at end of file diff --git a/docs/usermanual-ch03.xml b/docs/usermanual-ch03.xml deleted file mode 100644 index 3a26c55..0000000 --- a/docs/usermanual-ch03.xml +++ /dev/null @@ -1,77 +0,0 @@ -<chapter id="buffers-language-script-and-direction"> - <title>Buffers, language, script and direction</title> - <para> - The input to Harfbuzz is a series of Unicode characters, stored in a - buffer. In this chapter, we'll look at how to set up a buffer with - the text that we want and then customize the properties of the - buffer. - </para> - <section id="creating-and-destroying-buffers"> - <title>Creating and destroying buffers</title> - <para> - As we saw in our initial example, a buffer is created and - initialized with <literal>hb_buffer_create()</literal>. This - produces a new, empty buffer object, instantiated with some - default values and ready to accept your Unicode strings. - </para> - <para> - Harfbuzz manages the memory of objects that it creates (such as - buffers), so you don't have to. When you have finished working on - a buffer, you can call <literal>hb_buffer_destroy()</literal>: - </para> - <programlisting language="C"> - hb_buffer_t *buffer = hb_buffer_create(); - ... - hb_buffer_destroy(buffer); -</programlisting> - <para> - This will destroy the object and free its associated memory - - unless some other part of the program holds a reference to this - buffer. If you acquire a Harfbuzz buffer from another subsystem - and want to ensure that it is not garbage collected by someone - else destroying it, you should increase its reference count: - </para> - <programlisting language="C"> -void somefunc(hb_buffer_t *buffer) { - buffer = hb_buffer_reference(buffer); - ... -</programlisting> - <para> - And then decrease it once you're done with it: - </para> - <programlisting language="C"> - hb_buffer_destroy(buffer); -} -</programlisting> - <para> - To throw away all the data in your buffer and start from scratch, - call <literal>hb_buffer_reset(buffer)</literal>. If you want to - throw away the string in the buffer but keep the options, you can - instead call <literal>hb_buffer_clear_contents(buffer)</literal>. - </para> - </section> - <section id="adding-text-to-the-buffer"> - <title>Adding text to the buffer</title> - <para> - Now we have a brand new Harfbuzz buffer. Let's start filling it - with text! From Harfbuzz's perspective, a buffer is just a stream - of Unicode codepoints, but your input string is probably in one of - the standard Unicode character encodings (UTF-8, UTF-16, UTF-32) - </para> - </section> - <section id="setting-buffer-properties"> - <title>Setting buffer properties</title> - <para> - </para> - </section> - <section id="what-about-the-other-scripts"> - <title>What about the other scripts?</title> - <para> - </para> - </section> - <section id="customizing-unicode-functions"> - <title>Customizing Unicode functions</title> - <para> - </para> - </section> -</chapter> \ No newline at end of file diff --git a/docs/usermanual-ch04.xml b/docs/usermanual-ch04.xml deleted file mode 100644 index 01fcdc9..0000000 --- a/docs/usermanual-ch04.xml +++ /dev/null @@ -1,18 +0,0 @@ -<chapter id="fonts-and-faces"> - <title>Fonts and faces</title> - <section id="using-freetype"> - <title>Using FreeType</title> - <para> - </para> - </section> - <section id="using-harfbuzzs-native-opentype-implementation"> - <title>Using Harfbuzz's native OpenType implementation</title> - <para> - </para> - </section> - <section id="using-your-own-font-functions"> - <title>Using your own font functions</title> - <para> - </para> - </section> -</chapter> \ No newline at end of file diff --git a/docs/usermanual-ch05.xml b/docs/usermanual-ch05.xml deleted file mode 100644 index 470bab8..0000000 --- a/docs/usermanual-ch05.xml +++ /dev/null @@ -1,13 +0,0 @@ -<chapter id="shaping-and-shape-plans"> - <title>Shaping and shape plans</title> - <section id="opentype-features"> - <title>OpenType features</title> - <para> - </para> - </section> - <section id="plans-and-caching"> - <title>Plans and caching</title> - <para> - </para> - </section> -</chapter> \ No newline at end of file diff --git a/docs/usermanual-ch06.xml b/docs/usermanual-ch06.xml deleted file mode 100644 index ca674c0..0000000 --- a/docs/usermanual-ch06.xml +++ /dev/null @@ -1,8 +0,0 @@ -<sect1 id="glyph-information"> - <title>Glyph information</title> - <sect2 id="names-and-numbers"> - <title>Names and numbers</title> - <para> - </para> - </sect2> -</sect1> \ No newline at end of file diff --git a/docs/usermanual-fonts-and-faces.xml b/docs/usermanual-fonts-and-faces.xml new file mode 100644 index 0000000..01fcdc9 --- /dev/null +++ b/docs/usermanual-fonts-and-faces.xml @@ -0,0 +1,18 @@ +<chapter id="fonts-and-faces"> + <title>Fonts and faces</title> + <section id="using-freetype"> + <title>Using FreeType</title> + <para> + </para> + </section> + <section id="using-harfbuzzs-native-opentype-implementation"> + <title>Using Harfbuzz's native OpenType implementation</title> + <para> + </para> + </section> + <section id="using-your-own-font-functions"> + <title>Using your own font functions</title> + <para> + </para> + </section> +</chapter> \ No newline at end of file diff --git a/docs/usermanual-glyph-information.xml b/docs/usermanual-glyph-information.xml new file mode 100644 index 0000000..ca674c0 --- /dev/null +++ b/docs/usermanual-glyph-information.xml @@ -0,0 +1,8 @@ +<sect1 id="glyph-information"> + <title>Glyph information</title> + <sect2 id="names-and-numbers"> + <title>Names and numbers</title> + <para> + </para> + </sect2> +</sect1> \ No newline at end of file diff --git a/docs/usermanual-hello-harfbuzz.xml b/docs/usermanual-hello-harfbuzz.xml new file mode 100644 index 0000000..34db017 --- /dev/null +++ b/docs/usermanual-hello-harfbuzz.xml @@ -0,0 +1,183 @@ +<chapter id="hello-harfbuzz"> + <title>Hello, Harfbuzz</title> + <para> + Here's the simplest Harfbuzz that can possibly work. We will improve + it later. + </para> + <orderedlist numeration="arabic"> + <listitem> + <para> + Create a buffer and put your text in it. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + #include <hb.h> + hb_buffer_t *buf; + buf = hb_buffer_create(); + hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text)); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="2"> + <para> + Guess the script, language and direction of the buffer. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + hb_buffer_guess_segment_properties(buf); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="3"> + <para> + Create a face and a font, using FreeType for now. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + #include <hb-ft.h> + FT_New_Face(ft_library, font_path, index, &face) + hb_font_t *font = hb_ft_font_create(face); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="4"> + <para> + Shape! + </para> + </listitem> + </orderedlist> + <programlisting> + hb_shape(font, buf, NULL, 0); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="5"> + <para> + Get the glyph and position information. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + hb_glyph_info_t *glyph_info = hb_buffer_get_glyph_infos(buf, &glyph_count); + hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &glyph_count); +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="6"> + <para> + Iterate over each glyph. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + for (i = 0; i < glyph_count; ++i) { + glyphid = glyph_info[i].codepoint; + x_offset = glyph_pos[i].x_offset / 64.0; + y_offset = glyph_pos[i].y_offset / 64.0; + x_advance = glyph_pos[i].x_advance / 64.0; + y_advance = glyph_pos[i].y_advance / 64.0; + draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); + cursor_x += x_advance; + cursor_y += y_advance; + } +</programlisting> + <orderedlist numeration="arabic"> + <listitem override="7"> + <para> + Tidy up. + </para> + </listitem> + </orderedlist> + <programlisting language="C"> + hb_buffer_destroy(buf); + hb_font_destroy(hb_ft_font); +</programlisting> + <section id="what-harfbuzz-doesnt-do"> + <title>What Harfbuzz doesn't do</title> + <para> + The code above will take a UTF8 string, shape it, and give you the + information required to lay it out correctly on a single + horizontal (or vertical) line using the font provided. That is the + extent of Harfbuzz's responsibility. + </para> + <para> + If you are implementing a text layout engine you may have other + responsibilities, that Harfbuzz will not help you with: + </para> + <itemizedlist> + <listitem> + <para> + Harfbuzz won't help you with bidirectionality. If you want to + lay out text with mixed Hebrew and English, you will need to + ensure that the buffer provided to Harfbuzz has those + characters in the correct layout order. This will be different + from the logical order in which the Unicode text is stored. In + other words, the user will hit the keys in the following + sequence: + </para> + <programlisting> +A B C [space] × × × [space] D E F + </programlisting> + <para> + but will expect to see in the output: + </para> + <programlisting> +ABC ××× DEF + </programlisting> + <para> + This reordering is called <emphasis>bidi processing</emphasis> + ("bidi" is short for bidirectional), and there's an + algorithm as an annex to the Unicode Standard which tells you how + to reorder a string from logical order into presentation order. + Before sending your string to Harfbuzz, you may need to apply the + bidi algorithm to it. Libraries such as ICU and fribidi can do + this for you. + </para> + </listitem> + <listitem> + <para> + Harfbuzz won't help you with text that contains different font + properties. For instance, if you have the string "a + <emphasis>huge</emphasis> breakfast", and you expect + "huge" to be italic, you will need to send three + strings to Harfbuzz: <literal>a</literal>, in your Roman font; + <literal>huge</literal> using your italic font; and + <literal>breakfast</literal> using your Roman font again. + Similarly if you change font, font size, script, language or + direction within your string, you will need to shape each run + independently and then output them independently. Harfbuzz + expects to shape a run of characters sharing the same + properties. + </para> + </listitem> + <listitem> + <para> + Harfbuzz won't help you with line breaking, hyphenation or + justification. As mentioned above, it lays out the string + along a <emphasis>single line</emphasis> of, notionally, + infinite length. If you want to find out where the potential + word, sentence and line break points are in your text, you + could use the ICU library's break iterator functions. + </para> + <para> + Harfbuzz can tell you how wide a shaped piece of text is, which is + useful input to a justification algorithm, but it knows nothing + about paragraphs, lines or line lengths. Nor will it adjust the + space between words to fit them proportionally into a line. If you + want to layout text in paragraphs, you will probably want to send + each word of your text to Harfbuzz to determine its shaped width + after glyph substitutions, then work out how many words will fit + on a line, and then finally output each word of the line separated + by a space of the correct size to fully justify the paragraph. + </para> + </listitem> + </itemizedlist> + <para> + As a layout engine implementor, Harfbuzz will help you with the + interface between your text and your font, and that's something + that you'll need - what you then do with the glyphs that your font + returns is up to you. The example we saw above enough to get us + started using Harfbuzz. Now we are going to use the remainder of + Harfbuzz's API to refine that example and improve our text shaping + capabilities. + </para> + </section> +</chapter> \ No newline at end of file diff --git a/docs/usermanual-opentype-features.xml b/docs/usermanual-opentype-features.xml new file mode 100644 index 0000000..470bab8 --- /dev/null +++ b/docs/usermanual-opentype-features.xml @@ -0,0 +1,13 @@ +<chapter id="shaping-and-shape-plans"> + <title>Shaping and shape plans</title> + <section id="opentype-features"> + <title>OpenType features</title> + <para> + </para> + </section> + <section id="plans-and-caching"> + <title>Plans and caching</title> + <para> + </para> + </section> +</chapter> \ No newline at end of file diff --git a/docs/usermanual-what-is-harfbuzz.xml b/docs/usermanual-what-is-harfbuzz.xml new file mode 100644 index 0000000..3574d75 --- /dev/null +++ b/docs/usermanual-what-is-harfbuzz.xml @@ -0,0 +1,115 @@ +<chapter id="what-is-harfbuzz"> + <title>What is Harfbuzz?</title> + <para> + Harfbuzz is a <emphasis>text shaping engine</emphasis>. It solves + the problem of selecting and positioning glyphs from a font given a + Unicode string. + </para> + <section id="why-do-i-need-it"> + <title>Why do I need it?</title> + <para> + Text shaping is an integral part of preparing text for display. It + is a fairly low level operation; Harfbuzz is used directly by + graphic rendering libraries such as Pango, and the layout engines + in Firefox, LibreOffice and Chromium. Unless you are + <emphasis>writing</emphasis> one of these layout engines yourself, + you will probably not need to use Harfbuzz - normally higher level + libraries will turn text into glyphs for you. + </para> + <para> + However, if you <emphasis>are</emphasis> writing a layout engine + or graphics library yourself, you will need to perform text + shaping, and this is where Harfbuzz can help you. Here are some + reasons why you need it: + </para> + <itemizedlist> + <listitem> + <para> + OpenType fonts contain a set of glyphs, indexed by glyph ID. + The glyph ID within the font does not necessarily relate to a + Unicode codepoint. For instance, some fonts have the letter + "a" as glyph ID 1. To pull the right glyph out of + the font in order to display it, you need to consult a table + within the font (the "cmap" table) which maps + Unicode codepoints to glyph IDs. Text shaping turns codepoints + into glyph IDs. + </para> + </listitem> + <listitem> + <para> + Many OpenType fonts contain ligatures: combinations of + characters which are rendered together. For instance, it's + common for the <literal>fi</literal> combination to appear in + print as the single ligature "ï¬". Whether you should + render text as <literal>fi</literal> or "ï¬" does not + depend on the input text, but on the capabilities of the font + and the level of ligature application you wish to perform. + Text shaping involves querying the font's ligature tables and + determining what substitutions should be made. + </para> + </listitem> + <listitem> + <para> + While ligatures like "ï¬" are typographic + refinements, some languages <emphasis>require</emphasis> such + substitutions to be made in order to display text correctly. + In Tamil, when the letter "TTA" (à®) letter is + followed by "U" (à®), the combination should appear + as the single glyph "à®à¯". The sequence of Unicode + characters "à®à®" needs to be rendered as a single + glyph from the font - text shaping chooses the correct glyph + from the sequence of characters provided. + </para> + </listitem> + <listitem> + <para> + Similarly, each Arabic character has four different variants: + within a font, there will be glyphs for the initial, medial, + final, and isolated forms of each letter. Unicode only encodes + one codepoint per character, and so a Unicode string will not + tell you which glyph to use. Text shaping chooses the correct + form of the letter and returns the correct glyph from the font + that you need to render. + </para> + </listitem> + <listitem> + <para> + Other languages have marks and accents which need to be + rendered in certain positions around a base character. For + instance, the Moldovan language has the Cyrillic letter + "zhe" (ж) with a breve accent, like so: Ó. Some + fonts will contain this character as an individual glyph, + whereas other fonts will not contain a zhe-with-breve glyph + but expect the rendering engine to form the character by + overlaying the two glyphs ж and Ë. Where you should draw the + combining breve depends on the height of the preceding glyph. + Again, for Arabic, the correct positioning of vowel marks + depends on the height of the character on which you are + placing the mark. Text shaping tells you whether you have a + precomposed glyph within your font or if you need to compose a + glyph yourself out of combining marks, and if so, where to + position those marks. + </para> + </listitem> + </itemizedlist> + <para> + If this is something that you need to do, then you need a text + shaping engine: you could use Uniscribe if you are using Windows; + you could use CoreText on OS X; or you could use Harfbuzz. In the + rest of this manual, we are going to assume that you are the + implementor of a text layout engine. + </para> + </section> + <section id="why-is-it-called-harfbuzz"> + <title>Why is it called Harfbuzz?</title> + <para> + Harfbuzz began its life as text shaping code within the FreeType + project, (and you will see references to the FreeType authors + within the source code copyright declarations) but was then + abstracted out to its own project. This project is maintained by + Behdad Esfahbod, and named Harfbuzz. Originally, it was a shaping + engine for OpenType fonts - "Harfbuzz" is the Persian + for "open type". + </para> + </section> +</chapter> \ No newline at end of file commit 4dc2265918089ee08c6d82eed0cfd41e02d7d231 Author: Khaled Hosny <khaledho...@eglug.org> Date: Wed Dec 23 00:26:20 2015 +0400 Intro from freedesktop.org/wiki/Software/HarfBuzz/ diff --git a/docs/HarfBuzz.png b/docs/HarfBuzz.png new file mode 100644 index 0000000..d58d9fc Binary files /dev/null and b/docs/HarfBuzz.png differ diff --git a/docs/Makefile.am b/docs/Makefile.am index f605f24..64344b8 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -65,7 +65,8 @@ EXTRA_HFILES=$(top_builddir)/src/hb-version.h # Images to copy into HTML directory. # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png -HTML_IMAGES= +HTML_IMAGES= \ + HarfBuzz.png # Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). # e.g. content_files=running.sgml building.sgml changes-2.0.sgml diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index 60ff8e2..a7efbf8 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -8,10 +8,39 @@ <bookinfo> <title>HarfBuzz Manual</title> <releaseinfo> - for HarfBuzz &version;. + This document is for HarfBuzz &version;. <!--The latest version of this documentation can be found on-line at <ulink role="online-location" url="http://[SERVER]/libharfbuzz/index.html">http://[SERVER]/libharfbuzz/</ulink>.--> </releaseinfo> + <abstract> + <title>HarfBuzz</title> + <graphic fileref="HarfBuzz.png" format="PNG" align="center"/> + <para> + HarfBuzz is an <ulink url="http://www.microsoft.com/typography/otspec/">OpenType</ulink> + text shaping engine. + </para> + <para> + The current HarfBuzz codebase, formerly known as harfbuzz-ng, is + versioned 1.x.x and is stable and under active maintenance. This is + what is used in latest versions of Firefox, GNOME, ChromeOS, Chrome, + LibreOffice, XeTeX, Android, and KDE, among other places. The canonical + source tree is available + <ulink url="http://cgit.freedesktop.org/harfbuzz/">here</ulink>. + Also available on + <ulink url="https://github.com/behdad/harfbuzz">github</ulink>. + See below for release tarballs. + </para> + <para> + The old HarfBuzz codebase, these days known as harfbuzz-old, was + derived from <ulink url="http://freetype.org/">FreeType</ulink>, + <ulink url="http://pango.org/">Pango</ulink>, and + <ulink url="http://qt-project.org/">Qt</ulink> and is available + <ulink url="http://cgit.freedesktop.org/harfbuzz.old/">here</ulink>. + It is not actively developed or maintained, and is extremely buggy. All + users are encouraged to switch over to the new HarfBuzz as soon as + possible. There are no release tarballs of old HarfBuzz whatsoever. + </para> + </abstract> </bookinfo> <part> commit 22b07782ced6503a0bf33f2fe157b70540238f6d Author: Khaled Hosny <khaledho...@eglug.org> Date: Mon Dec 14 23:33:51 2015 +0400 Deploy docs to gh-pages branch from Travis builds Build docs in Travis and push them to the gh-pages branch, which makes them available at http://behdad.github.io/harfbuzz/ diff --git a/.ci/deploy-docs.sh b/.ci/deploy-docs.sh new file mode 100755 index 0000000..8c60a22 --- /dev/null +++ b/.ci/deploy-docs.sh @@ -0,0 +1,25 @@ +set -o errexit -o nounset + +if [ "$TRAVIS_OS_NAME" == "linux" -a "$CC" == "gcc" -a "$TRAVIS_PULL_REQUEST" == "false" -a "$TRAVIS_BRANCH" == "master" ] +then + DOCSDIR=build-docs + REVISION=$(git rev-parse --short HEAD) + + rm -rf $DOCSDIR || exit + mkdir $DOCSDIR + cd $DOCSDIR + + cp ../docs/html/* . + + git init + git config user.name "Travis CI" + git config user.email "tra...@harfbuzz.org" + git remote add upstream "https://$gh_to...@github.com/$TRAVIS_REPO_SLUG.git" + git fetch upstream + git reset upstream/gh-pages + + touch . + git add -A . + git commit -m "Rebuild docs for $REVISION" + git push -q upstream HEAD:gh-pages +fi diff --git a/.travis.yml b/.travis.yml index 817811c..798f5ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ env: - CFLAGS="-Werror --coverage" - CXXFLAGS="-Werror --coverage" - LDFLAGS="--coverage" + - secure: "EysLG1MB6WCvDVpls5jsJAYsXcbHTmSFYl11UlAQCNfU+MBv7qiuOR6im3tM4ISzt4TY+OQXxEktMFRT+8govLR4UWo8dwmZ4P/2GqMbsZNPVSLkbDEy6hVv7xe5X4mp+npHthY1Z1YOLKGAh/u1PymySZz6qAzsCZ6Fq/H5Ri8=" install: - if [ "$TRAVIS_OS_NAME" == "linux" ]; then pip install --user nose; fi - if [ "$TRAVIS_OS_NAME" == "linux" ]; then pip install --user cpp-coveralls; fi # for coveralls.io code coverage tracking @@ -23,11 +24,14 @@ install: script: - NOCONFIGURE=1 ./autogen.sh - export CONFIGURE_OPTS="--with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2" + - if [ "$TRAVIS_OS_NAME" == "linux" -a "$CC" == "gcc" ]; then export CONFIGURE_OPTS="$CONFIGURE_OPTS --enable-gtk-doc"; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then export CONFIGURE_OPTS="$CONFIGURE_OPTS --with-coretext"; fi - ./configure $CONFIGURE_OPTS - make - make check - if [ "$TRAVIS_OS_NAME" == "linux" -a "$CC" == "gcc" ]; then rm -f src/.libs/NONE.gcov; touch src/NONE; coveralls; fi +after_success: + - bash .ci/deploy-docs.sh notifications: irc: "irc.freenode.org#harfbuzz" email: harfbuzz@lists.freedesktop.org
_______________________________________________ HarfBuzz mailing list HarfBuzz@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/harfbuzz